Add a page_info flag to indicate whether free pages need a TLB flush
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 5 Feb 2009 12:09:10 +0000 (12:09 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 5 Feb 2009 12:09:10 +0000 (12:09 +0000)
on next use.

Apart from teh small performance gain of this, my primary motivation
is to avoid TLB flushes very early in boot, when the system is not yet
properly set up for cross-TLB shootdowns.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/page_alloc.c
xen/include/asm-ia64/mm.h
xen/include/asm-x86/mm.h

index de99f7333b22533bb5809268fbd62896f57c8b8c..3c84fd638a95ed3461bb07d5d12e29cfd82f2975 100644 (file)
@@ -399,10 +399,13 @@ static struct page_info *alloc_heap_pages(
         /* Reference count must continuously be zero for free pages. */
         BUG_ON(pg[i].count_info != 0);
 
-        /* Add in any extra CPUs that need flushing because of this page. */
-        cpus_andnot(extra_cpus_mask, cpu_online_map, mask);
-        tlbflush_filter(extra_cpus_mask, pg[i].tlbflush_timestamp);
-        cpus_or(mask, mask, extra_cpus_mask);
+        if ( pg[i].u.free.need_tlbflush )
+        {
+            /* Add in extra CPUs that need flushing because of this page. */
+            cpus_andnot(extra_cpus_mask, cpu_online_map, mask);
+            tlbflush_filter(extra_cpus_mask, pg[i].tlbflush_timestamp);
+            cpus_or(mask, mask, extra_cpus_mask);
+        }
 
         /* Initialise fields which have other uses for free pages. */
         pg[i].u.inuse.type_info = 0;
@@ -446,8 +449,9 @@ static void free_heap_pages(
         pg[i].count_info = 0;
 
         /* If a page has no owner it will need no safety TLB flush. */
-        pg[i].tlbflush_timestamp =
-            page_get_owner(&pg[i]) ? tlbflush_current_time() : 0;
+        pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL);
+        if ( pg[i].u.free.need_tlbflush )
+            pg[i].tlbflush_timestamp = tlbflush_current_time();
     }
 
     spin_lock(&heap_lock);
index d28aa565dc0273f08da545457d3ef0084c97dad6..5d35304f7d8fe5765b5d04b185ee667069292bb0 100644 (file)
@@ -62,6 +62,8 @@ struct page_info
         struct {
             /* Order-size of the free chunk this page is the head of. */
             u32 order;
+            /* Do TLBs need flushing for safety before next page use? */
+            bool_t need_tlbflush;
         } free;
 
     } u;
index 4a8c37f96a0c14a19de4783d2f8107271213fea4..8c1c675ebf5d8b7a1d27d22b7e8cbb170e7d2bd4 100644 (file)
@@ -66,6 +66,12 @@ struct page_info
             unsigned long count:26; /* Reference count */
         } sh;
 
+        /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
+        struct {
+            /* Do TLBs need flushing for safety before next page use? */
+            bool_t need_tlbflush;
+        } free;
+
     } u;
 
     union {